/**
 * @project_name thread
 * @package_name com.gxwz.thread
 * @file_name Java5SpecificConcurrentHashMapClass4Thread.java
 */
package com.gxwz.thread;

import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


/**
 * 本例中线程不再使用HashTable，请选择使用ConcurrentHashMap。 它的效率更高。
 * 
 * @author chendequan
 * @email 1527254027@qq.com
 * @datetime 2013-9-6 下午01:36:22
 * 
 */
public class Java5SpecificConcurrentHashMapClass4Thread {
	static final int threads = 1000;
	static final int NUMBER = 1000;

	public static void main(String[] args) throws Exception {
		Map<String, Integer> hashmapSync = Collections
				.synchronizedMap(new HashMap<String, Integer>());
		Map<String, Integer> concurrentHashMap = new ConcurrentHashMap<String, Integer>();
		Map<String, Integer> hashtable = new Hashtable<String, Integer>();
		long totalA = 0;
		long totalB = 0;
		long totalC = 0;

		for (int i = 0; i <= 10; i++) {
			System.out.println("A开始" + totalA);
			totalA += testPut(hashmapSync);
			System.out.println("A结束" + totalA);
			totalB += testPut(concurrentHashMap);
			totalC += testPut(hashtable);
		}

		System.out.println("Put time HashMapSync=" + totalA + "ms.");
		System.out.println("Put time CoucurrentHashMap=" + totalB + "ms.");
		System.out.println("Put time Hashtable=" + totalC + "ms.");
		totalA = 0;
		totalB = 0;
		totalC = 0;

		for (int i = 0; i <= 10; i++) {
			totalA += testGet(hashmapSync);
			totalB += testGet(concurrentHashMap);
			totalC += testGet(hashtable);
		}

		System.out.println("Put time HashMapSync=" + totalA + "ms.");
		System.out.println("Put time CoucurrentHashMap=" + totalB + "ms.");
		System.out.println("Put time Hashtable=" + totalC + "ms.");

	}

	/**
	 * @datetime 2013-9-7 上午02:38:01
	 * @param hashmapSync
	 * @return
	 */
	private static long testGet(Map<String, Integer> map) throws Exception {
			long start = System.currentTimeMillis();
			
			for (int i = 0; i < threads; i++)
				new MapPutThread(map).start();
			
			while (MapPutThread.counter > 0)
				Thread.sleep(1);
			
			return System.currentTimeMillis() - start;
	}

	/**
	 * @datetime 2013-9-7 上午02:37:50
	 * @param hashmapSync
	 * @return
	 */
	private static long testPut(Map<String, Integer> map) {
		long start = System.currentTimeMillis();

		for (int i = 0; i < threads; i++)
			new MapPutThread(map).start();

		try {
			while (MapPutThread.counter > 0)
				Thread.sleep(1);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		return System.currentTimeMillis() - start;
	}

}

class MapPutThread extends Thread {
	static int counter = 0;
	static Object lock = new Object();
	private Map<String, Integer> map;
	// 返回该线程的标识符。
	private String key = this.getId() + "";

	MapPutThread(Map<String, Integer> map) {
		synchronized (lock) {
			counter++;
		}
		this.map = map;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Thread#run()
	 */
	@Override
	public void run() {
		for (int i = 1; i <= Java5SpecificConcurrentHashMapClass4Thread.NUMBER; i++) {
			map.put(key, i);
		}

		synchronized (lock) {
			counter--;
		}
	}
}

